﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace AutosysLib.toolWrapper
{
    /// <summary>
    /// Helper tool for working with Autosys.
    /// Represents a set of status-info rows parsed from output of AUTOREP.cmd (or autorep.sh on Linux)
    /// </summary>
    public class Autorep_J_Result
    {
        public readonly List<Row> rows = new List<Row>();
        public readonly List<string> warnings = new List<string>();

        /// <summary>
        /// Represents a single status row from AUTOREP.cmd
        /// </summary>
        public class Row
        {
            public string leadingSpaces;
            public string jobName;
            public DateTime? lastStart, lastEnd;
            public string run;
            public string status;
            public int? exitCode;
            public override string ToString()
            {
                return "{Row " + jobName + " " + status + ", exit=" + exitCode + "}";
            }
        }
        public override string ToString()
        {
            return "{Autorep_J_Result " + rows.Count + " rows, " + warnings.Count + " warnings}";
        }

        // regex to match this sample line:
        // " aaa_child3                                                      09/18/2009 09:15:00  09/18/2009 09:30:32  FA 635198/1 666  ";
        static Regex reAutorepLine = new Regex(@"^(\s*)(\w+)\s+(-----|\d\d/\d\d/\d\d\d\d \d\d:\d\d:\d\d)\s+(-----|\d\d/\d\d/\d\d\d\d \d\d:\d\d:\d\d)\s+([A-Z]{2})\s+(\S+)"
            , RegexOptions.Compiled);

        public static DateTime? parseDate(string dateStr, List<string> warnings)
        {
            if (dateStr == "-----")
                return null;
            if (dateStr.Length == 19 && Char.IsDigit(dateStr[0]) && Char.IsDigit(dateStr[18]))
            {
                DateTime dt;
                if (DateTime.TryParseExact(dateStr, "MM/dd/yyyy HH:mm:ss", null, System.Globalization.DateTimeStyles.None, out dt))
                    return dt;
            }
            warnings.Add("Unable to parse date string " + dateStr);
            return null;
        }

        /// <summary>
        /// This is the 'main entry point' to parse and create rows
        /// </summary>
        public static Autorep_J_Result ParseLines(IEnumerable<string> lines)
        {
            Autorep_J_Result obj = new Autorep_J_Result();
            foreach (string ln in lines)
            {
                if (ln.StartsWith("CAUAJM_"))
                    obj.warnings.Add(ln);
                else if (ln.StartsWith("Job Name ") || ln.StartsWith("______________") || string.IsNullOrWhiteSpace(ln))
                    continue;
                else
                {
                    var mm = reAutorepLine.Match(ln);
                    if (mm.Success && mm.Groups.Count > 6)
                    {
                        var groups = mm.Groups;
                        DateTime? startDate = parseDate(groups[3].Value, obj.warnings);
                        DateTime? end_Date = parseDate(groups[4].Value, obj.warnings);
                        int lastMatchedPos = groups[6].Index + groups[6].Length;
                        string exitCodeStr = ln.Substring(lastMatchedPos+1);
                        exitCodeStr = exitCodeStr.Trim();
                        int? exitCode = null;
                        if(exitCodeStr.Length > 0 &&  Char.IsDigit(exitCodeStr[0])){
                            int code;
                            if(int.TryParse(exitCodeStr, out code))
                                exitCode = code;
                        }
                        Row row = new Row
                        {
                            leadingSpaces = groups[1].Value,
                            jobName = groups[2].Value,
                            lastStart = startDate,
                            lastEnd = end_Date,
                            run = groups[6].Value,
                            exitCode = exitCode,
                            status = groups[5].Value,
                        };
                        obj.rows.Add(row);
                    }
                }
            }
            return obj;
        }
    }
}
